#include <iostream>
#include "Thread.hpp"
#include <pthread.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string>
#include "InetAddr.hpp"

#define CONV(addr_ptr) ((sockaddr*)(addr_ptr))
struct ThreadData
{
    // ThreadData(int sockfd, InetAddr& addr)  //这样不行？？为什么
    ThreadData(int sockfd, sockaddr_in& addr) 
    :_sockfd(sockfd), _addr(addr)
    {}
    int _sockfd;
    InetAddr _addr;
};
void RecvRoutine(ThreadData& td)
{
    char buffer[1024];
    while(true)
    {
        sockaddr_in peer;
        socklen_t len = sizeof peer;
        int n = recvfrom(td._sockfd, buffer, sizeof buffer - 1, 0, CONV(&peer), &len);
        if(n > 0)
        {
            buffer[n] = 0;
            std::cout << buffer << std::endl;
        }
    }
}
void SendRoutine(ThreadData& td)
{
    while(true)
    {
        std::string message;
        std::cout << "please enter: ";
        getline(std::cin, message);

        int n = sendto(td._sockfd, message.c_str(), message.size(), 0, CONV(&td._addr._addr), sizeof td._addr._addr);
        if(n < 0)
            std::cout << "send error" << std::endl;
    }
}
int main(int argc, char* argv[])
{
    std::string serverip = argv[1];
    uint16_t serverport = std::stoi(argv[2]);

    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if(sockfd < 0)
    {
        return 1;
    }

    struct sockaddr_in server;
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = inet_addr(serverip.c_str());
    server.sin_port = htons(serverport);

    ThreadData td(sockfd, server);
    Thread<ThreadData> recver("receive", RecvRoutine, td);
    Thread<ThreadData> sender("sender", SendRoutine, td);

    recver.Start();
    sender.Start();

    recver.Join();
    sender.Join();
}